/*
 * Copyright (c) 2024 endless-sky
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef BASE_ALGO_MANAGER_IMPL_H
#define BASE_ALGO_MANAGER_IMPL_H

#include "../include/algo_manager.h"
#include "utils_noncopyable.h"
#include "utils_log.h"
#include "utils_callback_list.h"
#include "hal_algo.h"
#include <map>
#include <unordered_map>
#include <mutex>
#include <atomic>
#include <thread>
#include <memory>

namespace El {
namespace Algo {

/**
 * @brief 算法管理器实现类
 */
class AlgoManagerImpl : public IAlgoManager, public NoCopyable {
public:
    AlgoManagerImpl();
    ~AlgoManagerImpl() override;

    // IAlgoManager接口实现
    bool Start() override;
    void Stop() override;
    bool StartAlgo(AlgoType algoType) override;
    bool StopAlgo(AlgoType algoType) override;
    AlgoStatus GetAlgoStatus(AlgoType algoType) const override;
    void SetResultCallback(ResultCallback callback) override;
    bool SetConfidenceThreshold(AlgoType algoType, float threshold) override;

    // 新增多实例支持方法
    bool StartAlgoInstance(const std::string &instanceId, AlgoType algoType, const nlohmann::json &config);
    bool StopAlgoInstance(const std::string &instanceId);
    AlgoStatus GetAlgoInstanceStatus(const std::string &instanceId) const;
    std::vector<std::string> GetRunningInstances(AlgoType algoType = ALGO_TYPE_INVALID) const;

private:
    bool StopAllAlgos();
    bool LoadAndStartAlgosFromConfig();

private:
    /**
     * @brief 算法实例结构
     */
    struct AlgoInstance {
        std::string instanceId;    // 实例唯一ID
        AlgoType algoType;         // 算法类型
        AlgoStatus status;         // 算法状态
        bool initialized;          // 是否已初始化
        uint32_t frameCounter;     // 帧计数器
        uint64_t lastResultTime;   // 最后结果时间
        float confidenceThreshold; // 置信度阈值
        std::string configName;    // 对应的配置名称
        nlohmann::json config;     // 算法配置

        AlgoInstance()
            : instanceId(""),
              algoType(ALGO_TYPE_INVALID),
              status(AlgoStatus::IDLE),
              initialized(false),
              frameCounter(0),
              lastResultTime(0),
              confidenceThreshold(0.5f),
              configName("")
        {
        }
    };

    // HAL层回调函数
    static void OnAlgoResult(HAL_ALGO_REC_RESULT *result, void *pUserData);

    // 成员回调函数
    void HandleAlgoResult(const HAL_ALGO_REC_RESULT &halResult);

    // 辅助方法
    bool LoadAlgoConfigFromFile(const std::string &configName,
                                const nlohmann::json &config,
                                HAL_ALGO_CONFIG_S &halConfig);
    std::string GenerateInstanceId(AlgoType algoType, const std::string &configName);
    void NotifyStatusChange(const std::string &instanceId,
                            AlgoStatus oldStatus,
                            AlgoStatus newStatus,
                            const std::string &message);
    void UpdateAlgoStatus(const std::string &instanceId, AlgoStatus newStatus);
    bool ValidateAlgoConfig(AlgoType algoType, const nlohmann::json &config);
    std::string GetCurrentTimeString();
    uint64_t GetCurrentTimeMs();
    void StartResultMonitor();
    void StopResultMonitor();
    void ResultMonitorLoop();
    void DispatchEmptyResult(uint64_t timestampMs);
    void UpdateYoloClassLabels(const nlohmann::json& labelsConfig); // 热更新YOLO类别标签
    void OnFaceBestEvent(const nlohmann::json &event); // 人脸优选事件（来自选择器）

private:
    // 初始化状态
    std::atomic<bool> initialized_{false};

    // 算法实例管理 - 使用instanceId作为键支持多实例
    mutable std::mutex algoInstancesMutex_;
    std::unordered_map<std::string, std::unique_ptr<AlgoInstance>> algoInstances_;

    // 回调函数管理
    ResultCallback resultCallback_;
    mutable std::mutex resultCallbackMutex_;

    // HAL层回调注册状态
    std::atomic<bool> halCallbackRegistered_{false};

    // 统计信息
    std::atomic<uint64_t> totalFrameCount_{0};
    std::atomic<uint64_t> totalDetectionCount_{0};

    // 静态实例指针，用于HAL回调
    static AlgoManagerImpl *instance_;
    static std::mutex instanceMutex_;

    // 当前算法输入尺寸（用于结果归一化）
    std::atomic<uint32_t> algoInputWidth_{1024};
    std::atomic<uint32_t> algoInputHeight_{576};

    // 结果监控与空框回退状态
    std::unique_ptr<std::thread> resultMonitorThread_;
    std::atomic<bool> resultMonitorRunning_{false};
    std::mutex resultStateMutex_;
    uint64_t lastResultTimestampMs_{0};
    bool pendingEmptyNotification_{false};
    static constexpr uint64_t RESULT_CLEAR_DELAY_MS = 500; // ms
};

} // namespace Algo
} // namespace El

#endif // BASE_ALGO_MANAGER_IMPL_H
